#pragma once
#include <map>
#include <memory>
#include <list>
#include "game_log.h"
//T_ROOM必须拥有
//void init()
//bool check()
//两个方法
template <class T_ROOM, int PLAYER_NUM>
class MatchServer
{
public:
	MatchServer()
		:_AUTO_INCREMENT(0)
		,_is_rand(false)
	{
	}
	//变成开房卡模式
	bool ChangeRoomCardType()
	{
		vector<int> roomids;
		_roomids.clear();
		_is_rand = true;
		for (int id(100000); id < 1000000; id++)
		{
			roomids.push_back(id);
		}
		srand(time(NULL));
		random_shuffle(roomids.begin(), roomids.end());
		for (auto id : roomids)
		{
			_roomids.push_back(id);
		}
	}
	//新建房间
	void MallocRooms(int num)
	{
		for (int i(0); i < num; i++)
		{
			CreateNewRoom();
		}
	}
	//用下标获取房间指针
	std::shared_ptr<T_ROOM> operator[](int room_id)
	{
		auto itr = _all_rooms.find(room_id);
		if (itr == _all_rooms.end())
		{
			return nullptr;
		}
		return itr->second;
	}
	//匹配房间
	std::shared_ptr<T_ROOM> MatchingRoom(void* p_choose_rule = nullptr/*筛选规则*/)
	{
		int num = PLAYER_NUM - 1;
		while (num >= 0)
		{
			GAME_LOG.debug("match people %d: rooms:%d\n", num, _rooms[num].size());
			for (auto& itr : _rooms[num])
			{
				int rid = itr.first;
				auto proom = itr.second;
				if (!proom->check(p_choose_rule))
				{
					GAME_LOG.debug("check_fail\n");
					if (num == 0)//没人的场次匹配一次没匹配到，就算了，不再重试
					{
						break;
					}
					continue;
				}
				_rooms[num].erase(rid);
				_rooms[num + 1][rid] = proom;
				return proom;
			}
			num--;
		}
		return nullptr;
	}
	//离开房间
	bool LeaveRoom(int rid, int people = -1)
	{
		if ((*this)[rid] == nullptr)
		{
			return false;
		}
		int num = PLAYER_NUM;
		while (num >= 1)
		{
			GAME_LOG.debug("leave people %d: rooms:%d\n", num, _rooms[num].size());
			auto itr = _rooms[num].find(rid);
			if (itr != _rooms[num].end())
			{
				auto room = itr->second;
				_rooms[num].erase(itr);
				if (people == -1)
				{
					_rooms[num - 1][rid] = room;
				}
				else
				{
					_rooms[people][rid] = room;
				}
				return true;
			}
			num--;
		}
		return false;
	}
	//毁灭一个房间
	bool DestoryRoom(int rid)
	{
		auto itr = _all_rooms.find(rid);
		if (itr != _all_rooms.end())
		{
			if (_is_rand)
			{
				_roomids.push_back(rid);
			}
			_all_rooms.erase(rid);
			return true;
		}
		return false;
	}
	//创建一个新房间
	std::shared_ptr<T_ROOM> CreateNewRoom()
	{
		if (_is_rand)
		{
			auto roomid = _roomids.front();
			_roomids.pop_front();
			std::shared_ptr<T_ROOM> proom(new T_ROOM(roomid));
			proom->init();
			_all_rooms[roomid] = proom;
			return proom;
		}
		else
		{
			_AUTO_INCREMENT++;
			std::shared_ptr<T_ROOM> proom(new T_ROOM(_AUTO_INCREMENT));
			proom->init();
			_rooms[0][_AUTO_INCREMENT] = proom;
			_all_rooms[_AUTO_INCREMENT] = proom;
			return proom;
		}
	}
protected:
	bool _is_rand;
	int _AUTO_INCREMENT;
	std::map<int, std::shared_ptr<T_ROOM>>	_rooms[PLAYER_NUM + 1];
	std::map<int, std::shared_ptr<T_ROOM>>	_all_rooms;
	std::list<int>	_roomids;
};